home *** CD-ROM | disk | FTP | other *** search
/ PC Open 93 / PC Open 93 CD 1.bin / internet / AmphetaDesk / lib / XML / Simple.pm
Encoding:
Perl POD Document  |  2002-06-11  |  52.9 KB  |  1,930 lines

  1. # $Id: Simple.pm,v 1.2 2002/06/12 03:35:49 morbus Exp $
  2.  
  3. package XML::Simple;
  4.  
  5. =head1 NAME
  6.  
  7. XML::Simple - Easy API to read/write XML (esp config files)
  8.  
  9. =head1 SYNOPSIS
  10.  
  11.     use XML::Simple;
  12.  
  13.     my $ref = XMLin([<xml file or string>] [, <options>]);
  14.  
  15.     my $xml = XMLout($hashref [, <options>]);
  16.  
  17. Or the object oriented way:
  18.  
  19.     require XML::Simple;
  20.  
  21.     my $xs = new XML::Simple(options);
  22.  
  23.     my $ref = $xs->XMLin([<xml file or string>] [, <options>]);
  24.  
  25.     my $xml = $xs->XMLout($hashref [, <options>]);
  26.  
  27. =cut
  28.  
  29. # See after __END__ for more POD documentation
  30.  
  31.  
  32. # Load essentials here, other modules loaded on demand later
  33.  
  34. use strict;
  35. use Carp;
  36. require Exporter;
  37.  
  38.  
  39. ##############################################################################
  40. # Define some constants
  41. #
  42.  
  43. use vars qw($VERSION @ISA @EXPORT);
  44.  
  45. @ISA               = qw(Exporter);
  46. @EXPORT            = qw(XMLin XMLout);
  47. $VERSION           = '1.08';
  48.  
  49. my %CacheScheme    = (
  50.                        storable => [ \&StorableSave, \&StorableRestore ],
  51.                        memshare => [ \&MemShareSave, \&MemShareRestore ],
  52.                        memcopy  => [ \&MemCopySave,  \&MemCopyRestore  ]
  53.              );
  54.  
  55. my $DefaultValues  = 1;       # Used for locking only
  56. my @KnownOptIn     = qw(keyattr keeproot forcecontent contentkey noattr
  57.                         searchpath forcearray cache suppressempty parseropts);
  58. my @KnownOptOut    = qw(keyattr keeproot contentkey noattr
  59.                         rootname xmldecl outputfile noescape suppressempty);
  60. my @DefKeyAttr     = qw(name key id);
  61. my $DefRootName    = qq(opt);
  62. my $DefContentKey  = qq(content);
  63. my $DefXmlDecl     = qq(<?xml version='1.0' standalone='yes'?>);
  64.  
  65.  
  66. ##############################################################################
  67. # Globals for use by caching routines (access protected by locks)
  68. #
  69.  
  70. my %MemShareCache  = ();
  71. my %MemCopyCache   = ();
  72.  
  73.  
  74. ##############################################################################
  75. # Dummy 'lock' routine for non-threaded versions of Perl
  76. #
  77.  
  78. BEGIN {
  79.   if($] < 5.005) {
  80.     eval "sub lock {}";
  81.   }
  82. }
  83.  
  84.  
  85. ##############################################################################
  86. # Constructor for optional object interface.
  87. #
  88.  
  89. sub new {
  90.   my $class = ref($_[0]) || $_[0];      # Works as object or class method
  91.   shift;
  92.  
  93.   if(@_ % 2) {
  94.     croak "Default options must be name=>value pairs (odd number supplied)";
  95.   }
  96.  
  97.   my $self = { defopt => { @_ } };
  98.  
  99.   return(bless($self, $class));
  100. }
  101.  
  102.  
  103. ##############################################################################
  104. # Sub/Method: XMLin()
  105. #
  106. # Exported routine for slurping XML into a hashref - see pod for info.
  107. #
  108. # May be called as object method or as a plain function.
  109. #
  110. # Expects one arg for the source XML, optionally followed by a number of
  111. # name => value option pairs.
  112. #
  113.  
  114. sub XMLin {
  115.  
  116.   # If this is not a method call, create an object
  117.  
  118.   my $self;
  119.   if($_[0]  and  UNIVERSAL::isa($_[0], 'XML::Simple')) {
  120.     $self = shift;
  121.   }
  122.   else {
  123.     $self = new XML::Simple();
  124.   }
  125.  
  126.  
  127.   my $string = shift;
  128.  
  129.   $self->handle_options('in', @_);
  130.  
  131.  
  132.   # If no XML or filename supplied, look for scriptname.xml in script directory
  133.  
  134.   unless(defined($string))  {
  135.     
  136.     # Translate scriptname[.suffix] to scriptname.xml
  137.  
  138.     require File::Basename;
  139.  
  140.     my($ScriptName, $ScriptDir, $Extension) =
  141.       File::Basename::fileparse($0, '\.[^\.]+');
  142.  
  143.     $string = $ScriptName . '.xml';
  144.  
  145.  
  146.     # Add script directory to searchpath
  147.     
  148.     if($ScriptDir) {
  149.       unshift(@{$self->{opt}->{searchpath}}, $ScriptDir);
  150.     }
  151.   }
  152.   
  153.  
  154.   # Are we parsing from a file?  If so, is there a valid cache available?
  155.  
  156.   my($filename, $scheme);
  157.   unless($string =~ m{<.*?>}s  or  ref($string)  or  $string eq '-') {
  158.  
  159.     require File::Basename;
  160.     require File::Spec;
  161.  
  162.     $filename = $self->find_xml_file($string, @{$self->{opt}->{searchpath}});
  163.  
  164.     if($self->{opt}->{cache}) {
  165.       lock(%CacheScheme);
  166.       foreach $scheme (@{$self->{opt}->{cache}}) {
  167.     croak "Unsupported caching scheme: $scheme"
  168.       unless($CacheScheme{$scheme});
  169.  
  170.     my $opt = $CacheScheme{$scheme}->[1]->($filename);
  171.     return($opt) if($opt);
  172.       }
  173.     }
  174.   }
  175.   else {
  176.     delete($self->{opt}->{cache});
  177.     if($string eq '-') {
  178.       # Read from standard input
  179.       $filename = '-';
  180.     }
  181.   }
  182.  
  183.  
  184.   # Parsing is required, so let's get on with it
  185.  
  186.   my $tree =  $self->build_tree($filename, $string);
  187.  
  188.  
  189.   # Now work some magic on the resulting parse tree
  190.  
  191.   my($ref);
  192.   if($self->{opt}->{keeproot}) {
  193.     $ref = $self->collapse({}, @$tree);
  194.   }
  195.   else {
  196.     $ref = $self->collapse(@{$tree->[1]});
  197.   }
  198.  
  199.   if($self->{opt}->{cache}) {
  200.     $CacheScheme{$self->{opt}->{cache}->[0]}->[0]->($ref, $filename);
  201.   }
  202.  
  203.   return($ref);
  204. }
  205.  
  206.  
  207. ##############################################################################
  208. # Method: build_tree()
  209. #
  210. # If parsing is required, this is the routine that does it - using the 'Tree'
  211. # style of XML::Parser.
  212. #
  213. # If you're planning to override this routine, your version should return the
  214. # same type of data structure as an XML::Parser Tree (summarised in the 
  215. # comments for the collapse() routine below).
  216. #
  217.  
  218. sub build_tree {
  219.   my $self     = shift;
  220.   my $filename = shift;
  221.   my $string   = shift;
  222.  
  223.  
  224.   {
  225.     local($^W) = 0;      # Suppress warning from Expat.pm re File::Spec::load()
  226.     require XML::Parser; # We didn't need it until now
  227.   }
  228.  
  229.   my $xp = new XML::Parser(Style => 'Tree', @{$self->{opt}->{parseropts}});
  230.   my($tree);
  231.  
  232.  
  233.   # Work around wierd read error problem in expat with '-'
  234.  
  235.   if($filename  and  $filename eq '-') {
  236.     local($/) = undef;
  237.     $string = <STDIN>;
  238.     $filename = undef;
  239.   }
  240.   if($filename) {
  241.     # $tree = $xp->parsefile($filename);  # Changed due to prob w/mod_perl
  242.     local(*XML_FILE);
  243.     open(XML_FILE, "<$filename") || croak qq($filename - $!);
  244.     $tree = $xp->parse(*XML_FILE);
  245.     close(XML_FILE);
  246.   }
  247.   else {
  248.     $tree = $xp->parse($string);
  249.   }
  250.  
  251.   return($tree);
  252. }
  253.  
  254.  
  255. ##############################################################################
  256. # Sub: StorableSave()
  257. #
  258. # Wrapper routine for invoking Storable::nstore() to cache a parsed data
  259. # structure.
  260. #
  261.  
  262. sub StorableSave {
  263.   my($data, $filename) = @_;
  264.  
  265.   my $cachefile = $filename;
  266.   $cachefile =~ s{(\.xml)?$}{.stor};
  267.  
  268.   require Storable;           # We didn't need it until now
  269.   
  270.   Storable::nstore($data, $cachefile);
  271.   
  272. }
  273.  
  274.  
  275. ##############################################################################
  276. # Sub: StorableRestore()
  277. #
  278. # Wrapper routine for invoking Storable::retrieve() to read a cached parsed
  279. # data structure.  Only returns cached data if the cache file exists and is
  280. # newer than the source XML file.
  281. #
  282.  
  283. sub StorableRestore {
  284.   my($filename) = @_;
  285.   
  286.   my $cachefile = $filename;
  287.   $cachefile =~ s{(\.xml)?$}{.stor};
  288.  
  289.   return unless(-r $cachefile);
  290.   return unless((stat($cachefile))[9] > (stat($filename))[9]);
  291.  
  292.   unless($INC{'Storable.pm'}) {
  293.     require Storable;           # We didn't need it until now
  294.   }
  295.   
  296.   return(Storable::retrieve($cachefile));
  297.   
  298. }
  299.  
  300.  
  301. ##############################################################################
  302. # Sub: MemShareSave()
  303. #
  304. # Takes the supplied data structure reference and stores it away in a global
  305. # hash structure.
  306. #
  307.  
  308. sub MemShareSave {
  309.   my($data, $filename) = @_;
  310.  
  311.   lock(%MemShareCache);
  312.   $MemShareCache{$filename} = [time(), $data];
  313. }
  314.  
  315.  
  316. ##############################################################################
  317. # Sub: MemShareRestore()
  318. #
  319. # Takes a filename and looks in a global hash for a cached parsed version.
  320. #
  321.  
  322. sub MemShareRestore {
  323.   my($filename) = @_;
  324.   
  325.   lock(%MemShareCache);
  326.   return unless($MemShareCache{$filename});
  327.   return unless($MemShareCache{$filename}->[0] > (stat($filename))[9]);
  328.  
  329.   return($MemShareCache{$filename}->[1]);
  330.   
  331. }
  332.  
  333.  
  334. ##############################################################################
  335. # Sub: MemCopySave()
  336. #
  337. # Takes the supplied data structure and stores a copy of it in a global hash
  338. # structure.
  339. #
  340.  
  341. sub MemCopySave {
  342.   my($data, $filename) = @_;
  343.  
  344.   lock(%MemCopyCache);
  345.   unless($INC{'Storable.pm'}) {
  346.     require Storable;           # We didn't need it until now
  347.   }
  348.   
  349.   $MemCopyCache{$filename} = [time(), Storable::dclone($data)];
  350. }
  351.  
  352.  
  353. ##############################################################################
  354. # Sub: MemCopyRestore()
  355. #
  356. # Takes a filename and looks in a global hash for a cached parsed version.
  357. # Returns a reference to a copy of that data structure.
  358. #
  359.  
  360. sub MemCopyRestore {
  361.   my($filename) = @_;
  362.   
  363.   lock(%MemCopyCache);
  364.   return unless($MemCopyCache{$filename});
  365.   return unless($MemCopyCache{$filename}->[0] > (stat($filename))[9]);
  366.  
  367.   return(Storable::dclone($MemCopyCache{$filename}->[1]));
  368.   
  369. }
  370.  
  371.  
  372. ##############################################################################
  373. # Sub/Method: XMLout()
  374. #
  375. # Exported routine for 'unslurping' a data structure out to XML.
  376. #
  377. # Expects a reference to a data structure and an optional list of option
  378. # name => value pairs.
  379. #
  380.  
  381. sub XMLout {
  382.  
  383.   # If this is not a method call, create an object
  384.  
  385.   my $self;
  386.   if($_[0]  and  UNIVERSAL::isa($_[0], 'XML::Simple')) {
  387.     $self = shift;
  388.   }
  389.   else {
  390.     $self = new XML::Simple();
  391.   }
  392.  
  393.  
  394.   my $ref = shift;
  395.  
  396.   $self->handle_options('out', @_);
  397.  
  398.  
  399.   # Wrap top level arrayref in a hash
  400.  
  401.   if(ref($ref) eq 'ARRAY') {
  402.     $ref = { anon => $ref };
  403.   }
  404.  
  405.  
  406.   # Extract rootname from top level hash if keeproot enabled
  407.  
  408.   if($self->{opt}->{keeproot}) {
  409.     my(@keys) = keys(%$ref);
  410.     if(@keys == 1) {
  411.       $ref = $ref->{$keys[0]};
  412.       $self->{opt}->{rootname} = $keys[0];
  413.     }
  414.   }
  415.   
  416.   # Ensure there are no top level attributes if we're not adding root elements
  417.  
  418.   elsif($self->{opt}->{rootname} eq '') {
  419.     if(ref($ref) eq 'HASH') {
  420.       my $refsave = $ref;
  421.       $ref = {};
  422.       foreach (keys(%$refsave)) {
  423.     if(ref($refsave->{$_})) {
  424.       $ref->{$_} = $refsave->{$_};
  425.     }
  426.     else {
  427.       $ref->{$_} = [ $refsave->{$_} ];
  428.     }
  429.       }
  430.     }
  431.   }
  432.  
  433.  
  434.   # Encode the hashref and write to file if necessary
  435.  
  436.   my $xml = $self->value_to_xml($ref, $self->{opt}->{rootname}, {}, '');
  437.   if($self->{opt}->{xmldecl}) {
  438.     $xml = $self->{opt}->{xmldecl} . "\n" . $xml;
  439.   }
  440.  
  441.   if($self->{opt}->{outputfile}) {
  442.     if(ref($self->{opt}->{outputfile})) {
  443.       return($self->{opt}->{outputfile}->print($xml));
  444.     }
  445.     else {
  446.       open(_XML_SIMPLE_OUT_, ">$self->{opt}->{outputfile}") ||
  447.         croak "open($self->{opt}->{outputfile}): $!";
  448.       print _XML_SIMPLE_OUT_ $xml || croak "print: $!";
  449.       close(_XML_SIMPLE_OUT_);
  450.     }
  451.   }
  452.   else {
  453.     return($xml);
  454.   }
  455. }
  456.  
  457.  
  458. ##############################################################################
  459. # Method: handle_options()
  460. #
  461. # Helper routine for both XMLin() and XMLout().  Both routines handle their
  462. # first argument and assume all other args are options handled by this routine.
  463. # Saves a hash of options in $self->{opt}.
  464. #
  465. # If default options were passed to the constructor, they will be retrieved
  466. # here and merged with options supplied to the method call.
  467. #
  468. # First argument should be the string 'in' or the string 'out'.
  469. #
  470. # Remaining arguments should be name=>value pairs.  Sets up default values
  471. # for options not supplied.  Unrecognised options are a fatal error.
  472. #
  473.  
  474. sub handle_options  {
  475.   my $self = shift;
  476.   my $dirn = shift;
  477.  
  478.  
  479.   lock($DefaultValues);
  480.  
  481.   # Determine valid options based on context
  482.  
  483.   my %known_opt; 
  484.   if($dirn eq 'in') {
  485.     @known_opt{@KnownOptIn} = @KnownOptIn;
  486.   }
  487.   else {
  488.     @known_opt{@KnownOptOut} = @KnownOptOut;
  489.   }
  490.  
  491.  
  492.   # Store supplied options in hashref and weed out invalid ones
  493.  
  494.   if(@_ % 2) {
  495.     croak "Options must be name=>value pairs (odd number supplied)";
  496.   }
  497.   my $opt = { @_ };
  498.   $self->{opt} = $opt;
  499.  
  500.   foreach (keys(%$opt)) {
  501.     croak "Unrecognised option: $_"
  502.       unless($known_opt{$_});
  503.   }
  504.  
  505.  
  506.   # Merge in options passed to constructor
  507.  
  508.   if($self->{defopt}) {
  509.     foreach (keys(%known_opt)) {
  510.       unless(exists($opt->{$_})) {
  511.     if(exists($self->{defopt}->{$_})) {
  512.       $opt->{$_} = $self->{defopt}->{$_};
  513.     }
  514.       }
  515.     }
  516.   }
  517.  
  518.  
  519.   # Set sensible defaults if not supplied
  520.   
  521.   if(exists($opt->{rootname})) {
  522.     unless(defined($opt->{rootname})) {
  523.       $opt->{rootname} = '';
  524.     }
  525.   }
  526.   else {
  527.     $opt->{rootname} = $DefRootName;
  528.   }
  529.   
  530.   if($opt->{xmldecl}  and  $opt->{xmldecl} eq '1') {
  531.     $opt->{xmldecl} = $DefXmlDecl;
  532.   }
  533.  
  534.   unless(exists($opt->{contentkey})) {
  535.     $opt->{contentkey} = $DefContentKey;
  536.   }
  537.  
  538.  
  539.   # Cleanups for values assumed to be arrays later
  540.  
  541.   if($opt->{searchpath}) {
  542.     unless(ref($opt->{searchpath})) {
  543.       $opt->{searchpath} = [ $opt->{searchpath} ];
  544.     }
  545.   }
  546.   else  {
  547.     $opt->{searchpath} = [ ];
  548.   }
  549.  
  550.   if($opt->{cache}  and !ref($opt->{cache})) {
  551.     $opt->{cache} = [ $opt->{cache} ];
  552.   }
  553.   
  554.   unless(exists($opt->{parseropts})) {
  555.     $opt->{parseropts} = [ ];
  556.   }
  557.  
  558.  
  559.   # Special cleanup for {keyattr} which could be arrayref or hashref or left
  560.   # to default to arrayref
  561.  
  562.   if(exists($opt->{keyattr}))  {
  563.     if(ref($opt->{keyattr})) {
  564.       if(ref($opt->{keyattr}) eq 'HASH') {
  565.  
  566.     # Make a copy so we can mess with it
  567.  
  568.     $opt->{keyattr} = { %{$opt->{keyattr}} };
  569.  
  570.     
  571.     # Convert keyattr => { elem => '+attr' }
  572.     # to keyattr => { elem => [ 'attr', '+' ] } 
  573.  
  574.     foreach (keys(%{$opt->{keyattr}})) {
  575.       if($opt->{keyattr}->{$_} =~ /^(\+|-)?(.*)$/) {
  576.         $opt->{keyattr}->{$_} = [ $2, ($1 ? $1 : '') ];
  577.       }
  578.       else {
  579.         delete($opt->{keyattr}->{$_}); # Never reached (famous last words?)
  580.       }
  581.     }
  582.       }
  583.       else {
  584.     if(@{$opt->{keyattr}} == 0) {
  585.       delete($opt->{keyattr});
  586.     }
  587.       }
  588.     }
  589.     else {
  590.       $opt->{keyattr} = [ $opt->{keyattr} ];
  591.     }
  592.   }
  593.   else  {
  594.     $opt->{keyattr} = [ @DefKeyAttr ];
  595.   }
  596.  
  597.   
  598.   # Special cleanup for {forcearray} which could be arrayref or boolean
  599.   # or left to default to 0
  600.  
  601.   if(exists($opt->{forcearray})) {
  602.     if(ref($opt->{forcearray}) eq 'ARRAY') {
  603.       if(@{$opt->{forcearray}}) {
  604.         $opt->{forcearray} = { (
  605.       map { $_ => 1 } @{$opt->{forcearray}}
  606.     ) };
  607.       }
  608.       else {
  609.         $opt->{forcearray} = 0;
  610.       }
  611.     }
  612.     else {
  613.       $opt->{forcearray} = ( $opt->{forcearray} ? 1 : 0 );
  614.     }
  615.   }
  616.   else {
  617.     $opt->{forcearray} = 0;
  618.   }
  619.  
  620. }
  621.  
  622.  
  623. ##############################################################################
  624. # Method: find_xml_file()
  625. #
  626. # Helper routine for XMLin().
  627. # Takes a filename, and a list of directories, attempts to locate the file in
  628. # the directories listed.
  629. # Returns a full pathname on success; croaks on failure.
  630. #
  631.  
  632. sub find_xml_file  {
  633.   my $self = shift;
  634.   my $file = shift;
  635.   my @search_path = @_;
  636.  
  637.  
  638.   my($filename, $filedir) =
  639.     File::Basename::fileparse($file);
  640.  
  641.   if($filename ne $file) {        # Ignore searchpath if dir component
  642.     return($file) if(-e $file);
  643.   }
  644.   else {
  645.     my($path);
  646.     foreach $path (@search_path)  {
  647.       my $fullpath = File::Spec->catfile($path, $file);
  648.       return($fullpath) if(-e $fullpath);
  649.     }
  650.   }
  651.  
  652.   # If user did not supply a search path, default to current directory
  653.  
  654.   if(!@search_path) {
  655.     if(-e $file) {
  656.       return($file);
  657.     }
  658.     croak "File does not exist: $file";
  659.   }
  660.  
  661.   croak "Could not find $file in ", join(':', @search_path);
  662. }
  663.  
  664.  
  665. ##############################################################################
  666. # Method: collapse()
  667. #
  668. # Helper routine for XMLin().  This routine really comprises the 'smarts' (or
  669. # value add) of this module.
  670. #
  671. # Takes the parse tree that XML::Parser produced from the supplied XML and
  672. # recurses through it 'collapsing' unnecessary levels of indirection (nested
  673. # arrays etc) to produce a data structure that is easier to work with.
  674. #
  675. # Elements in the original parser tree are represented as an element name
  676. # followed by an arrayref.  The first element of the array is a hashref
  677. # containing the attributes.  The rest of the array contains a list of any
  678. # nested elements as name+arrayref pairs:
  679. #
  680. #  <element name>, [ { <attribute hashref> }, <element name>, [ ... ], ... ]
  681. #
  682. # The special element name '0' (zero) flags text content.
  683. #
  684. # This routine cuts down the noise by discarding any text content consisting of
  685. # only whitespace and then moves the nested elements into the attribute hash
  686. # using the name of the nested element as the hash key and the collapsed
  687. # version of the nested element as the value.  Multiple nested elements with
  688. # the same name will initially be represented as an arrayref, but this may be
  689. # 'folded' into a hashref depending on the value of the keyattr option.
  690. #
  691.  
  692. sub collapse {
  693.   my $self = shift;;
  694.  
  695.  
  696.   # Start with the hash of attributes
  697.   
  698.   my $attr  = shift;
  699.   $attr = {} if($self->{opt}->{noattr});    # Discard if 'noattr' set
  700.  
  701.  
  702.   # Add any nested elements
  703.  
  704.   my($key, $val);
  705.   while(@_) {
  706.     $key = shift;
  707.     $val = shift;
  708.  
  709.     if(ref($val)) {
  710.       $val = $self->collapse(@$val);
  711.       next if(!defined($val)  and  $self->{opt}->{suppressempty});
  712.     }
  713.     elsif($key eq '0') {
  714.       next if($val =~ m{^\s*$}s);  # Skip all whitespace content
  715.       if(!%$attr  and  !@_) {      # Short circuit text in tag with no attr
  716.         return($self->{opt}->{forcecontent} ?
  717.            { $self->{opt}->{contentkey} => $val } : $val
  718.           );
  719.       }
  720.       $key = $self->{opt}->{contentkey};
  721.     }
  722.  
  723.  
  724.     # Combine duplicate attributes into arrayref if required
  725.  
  726.     if(exists($attr->{$key})) {
  727.       if(ref($attr->{$key}) eq 'ARRAY') {
  728.         push(@{$attr->{$key}}, $val);
  729.       }
  730.       else {
  731.         $attr->{$key} = [ $attr->{$key}, $val ];
  732.       }
  733.     }
  734.     elsif(ref($val) eq 'ARRAY') {  # Handle anonymous arrays
  735.       $attr->{$key} = [ $val ];
  736.     }
  737.     else {
  738.       if( $key ne $self->{opt}->{contentkey}  and
  739.           (
  740.         ($self->{opt}->{forcearray} == 1) or
  741.         ( 
  742.           (ref($self->{opt}->{forcearray}) eq 'HASH') and
  743.           ($self->{opt}->{forcearray}->{$key})
  744.         )
  745.       )
  746.     ) {
  747.     $attr->{$key} = [ $val ];
  748.       }
  749.       else {
  750.     $attr->{$key} = $val;
  751.       }
  752.     }
  753.   }
  754.  
  755.  
  756.   # Turn arrayrefs into hashrefs if key fields present
  757.  
  758.   my $count = 0;
  759.   if($self->{opt}->{keyattr}) {
  760.     while(($key,$val) = each %$attr) {
  761.       if(ref($val) eq 'ARRAY') {
  762.     $attr->{$key} = $self->array_to_hash($key, $val);
  763.       }
  764.       $count++;
  765.     }
  766.   }
  767.  
  768.  
  769.   # Fold hashes containing a single anonymous array up into just the array
  770.  
  771.   if($count == 1  and  ref($attr->{anon}) eq 'ARRAY') {
  772.     return($attr->{anon});
  773.   }
  774.  
  775.  
  776.   # Do the right thing if hash is empty, otherwise just return it
  777.  
  778.   if(!%$attr  and  exists($self->{opt}->{suppressempty})) {
  779.     if(defined($self->{opt}->{suppressempty})  and
  780.        $self->{opt}->{suppressempty} eq '') {
  781.       return('');
  782.     }
  783.     return(undef);
  784.   }
  785.  
  786.   return($attr)
  787.  
  788. }
  789.  
  790.  
  791. ##############################################################################
  792. # Method: array_to_hash()
  793. #
  794. # Helper routine for collapse().
  795. # Attempts to 'fold' an array of hashes into an hash of hashes.  Returns a
  796. # reference to the hash on success or the original array if folding is
  797. # not possible.  Behaviour is controlled by 'keyattr' option.
  798. #
  799.  
  800. sub array_to_hash {
  801.   my $self     = shift;
  802.   my $name     = shift;
  803.   my $arrayref = shift;
  804.  
  805.   my $hashref  = {};
  806.  
  807.   my($i, $key, $val, $flag);
  808.  
  809.  
  810.   # Handle keyattr => { .... }
  811.  
  812.   if(ref($self->{opt}->{keyattr}) eq 'HASH') {
  813.     return($arrayref) unless(exists($self->{opt}->{keyattr}->{$name}));
  814.     ($key, $flag) = @{$self->{opt}->{keyattr}->{$name}};
  815.     for($i = 0; $i < @$arrayref; $i++)  {
  816.       if(ref($arrayref->[$i]) eq 'HASH' and exists($arrayref->[$i]->{$key})) {
  817.     $val = $arrayref->[$i]->{$key};
  818.     $hashref->{$val} = { %{$arrayref->[$i]} };
  819.     $hashref->{$val}->{"-$key"} = $hashref->{$val}->{$key} if($flag eq '-');
  820.     delete $hashref->{$val}->{$key} unless($flag eq '+');
  821.       }
  822.       else {
  823.     carp "Warning: <$name> element has no '$key' key attribute" if($^W);
  824.     return($arrayref);
  825.       }
  826.     }
  827.   }
  828.  
  829.  
  830.   # Or assume keyattr => [ .... ]
  831.  
  832.   else {
  833.     ELEMENT: for($i = 0; $i < @$arrayref; $i++)  {
  834.       return($arrayref) unless(ref($arrayref->[$i]) eq 'HASH');
  835.  
  836.       foreach $key (@{$self->{opt}->{keyattr}}) {
  837.     if(defined($arrayref->[$i]->{$key}))  {
  838.       $val = $arrayref->[$i]->{$key};
  839.       $hashref->{$val} = { %{$arrayref->[$i]} };
  840.       delete $hashref->{$val}->{$key};
  841.       next ELEMENT;
  842.     }
  843.       }
  844.  
  845.       return($arrayref);    # No keyfield matched
  846.     }
  847.   }
  848.  
  849.   return($hashref);
  850. }
  851.  
  852.  
  853. ##############################################################################
  854. # Method: value_to_xml()
  855. #
  856. # Helper routine for XMLout() - recurses through a data structure building up
  857. # and returning an XML representation of that structure as a string.
  858. # Arguments expected are:
  859. # - the data structure to be encoded (usually a reference)
  860. # - the XML tag name to use for this item
  861. # - a hashref of references already encoded (to detect recursive structures)
  862. # - a string of spaces for use as the current indent level
  863. #
  864.  
  865. sub value_to_xml {
  866.   my $self = shift;;
  867.  
  868.  
  869.   # Grab the other arguments
  870.  
  871.   my($ref, $name, $encoded, $indent) = @_;
  872.  
  873.   my $named = (defined($name) and $name ne '' ? 1 : 0);
  874.  
  875.   my $nl = "\n";
  876.  
  877.   if(ref($ref)) {
  878.     croak "recursive data structures not supported" if($encoded->{$ref});
  879.     $encoded->{$ref} = $ref;
  880.   }
  881.   else {
  882.     if($named) {
  883.       return(join('',
  884.               $indent, '<', $name, '>',
  885.           ($self->{opt}->{noescape} ? $ref : $self->escape_value($ref)),
  886.               '</', $name, ">", $nl
  887.         ));
  888.     }
  889.     else {
  890.       return("$ref$nl");
  891.     }
  892.   }
  893.  
  894.   # Unfold hash to array if possible
  895.  
  896.   if(ref($ref) eq 'HASH'               # It is a hash
  897.      and %$ref                         # and it's not empty
  898.      and $self->{opt}->{keyattr}       # and folding is enabled
  899.      and $indent                       # and its not the root element
  900.   ) {
  901.     $ref = $self->hash_to_array($name, $ref);
  902.   }
  903.  
  904.   
  905.   my @result = ();
  906.   my($key, $value);
  907.  
  908.  
  909.   # Handle hashrefs
  910.  
  911.   if(ref($ref) eq 'HASH') {
  912.     my @nested = ();
  913.     my $text_content = undef;
  914.     if($named) {
  915.       push @result, $indent, '<', $name;
  916.     }
  917.  
  918.     if(%$ref) {
  919.       while(($key, $value) = each(%$ref)) {
  920.     next if(substr($key, 0, 1) eq '-');
  921.     if(!defined($value)) {
  922.       unless(exists($self->{opt}->{suppressempty})
  923.          and !defined($self->{opt}->{suppressempty})
  924.       ) {
  925.         carp 'Use of uninitialized value';
  926.       }
  927.       $value = {};
  928.     }
  929.     if(ref($value)  or  $self->{opt}->{noattr}) {
  930.       push @nested,
  931.         $self->value_to_xml($value, $key, $encoded, "$indent  ");
  932.     }
  933.     else {
  934.       $value = $self->escape_value($value) unless($self->{opt}->{noescape});
  935.       if($key eq $self->{opt}->{contentkey}) {
  936.         $text_content = $value;
  937.       }
  938.       else {
  939.         push @result, ' ', $key, '="', $value , '"';
  940.       }
  941.     }
  942.       }
  943.     }
  944.     else {
  945.       $text_content = '';
  946.     }
  947.  
  948.     if(@nested  or  defined($text_content)) {
  949.       if($named) {
  950.         push @result, ">";
  951.     if(defined($text_content)) {
  952.       push @result, $text_content;
  953.       $nested[0] =~ s/^\s+// if(@nested);
  954.     }
  955.     else {
  956.       push @result, $nl;
  957.     }
  958.     if(@nested) {
  959.       push @result, @nested, $indent;
  960.     }
  961.     push @result, '</', $name, ">", $nl;
  962.       }
  963.       else {
  964.         push @result, @nested;             # Special case if no root elements
  965.       }
  966.     }
  967.     else {
  968.       push @result, " />", $nl;
  969.     }
  970.   }
  971.  
  972.  
  973.   # Handle arrayrefs
  974.  
  975.   elsif(ref($ref) eq 'ARRAY') {
  976.     foreach $value (@$ref) {
  977.       if(!ref($value)) {
  978.         push @result,
  979.          $indent, '<', $name, '>',
  980.          ($self->{opt}->{noescape} ? $value : $self->escape_value($value)),
  981.          '</', $name, ">\n";
  982.       }
  983.       elsif(ref($value) eq 'HASH') {
  984.     push @result, $self->value_to_xml($value, $name, $encoded, $indent);
  985.       }
  986.       else {
  987.     push @result,
  988.            $indent, '<', $name, ">\n",
  989.            $self->value_to_xml($value, 'anon', $encoded, "$indent  "),
  990.            $indent, '</', $name, ">\n";
  991.       }
  992.     }
  993.   }
  994.  
  995.   else {
  996.     croak "Can't encode a value of type: " . ref($ref);
  997.   }
  998.  
  999.   return(join('', @result));
  1000. }
  1001.  
  1002.  
  1003. ##############################################################################
  1004. # Method: escape_value()
  1005. #
  1006. # Helper routine for automatically escaping values for XMLout().
  1007. # Expects a scalar data value.  Returns escaped version.
  1008. #
  1009.  
  1010. sub escape_value {
  1011.   my $self = shift;
  1012.  
  1013.   my($data) = @_;
  1014.  
  1015.   $data =~ s/&/&/sg;
  1016.   $data =~ s/</</sg;
  1017.   $data =~ s/>/>/sg;
  1018.   $data =~ s/"/"/sg;
  1019.  
  1020.   return($data);
  1021. }
  1022.  
  1023.  
  1024. ##############################################################################
  1025. # Method: hash_to_array()
  1026. #
  1027. # Helper routine for value_to_xml().
  1028. # Attempts to 'unfold' a hash of hashes into an array of hashes.  Returns a
  1029. # reference to the array on success or the original hash if unfolding is
  1030. # not possible.
  1031. #
  1032.  
  1033. sub hash_to_array {
  1034.   my $self    = shift;
  1035.   my $parent  = shift;
  1036.   my $hashref = shift;
  1037.  
  1038.   my $arrayref = [];
  1039.  
  1040.   my($key, $value);
  1041.  
  1042.   foreach $key (keys(%$hashref)) {
  1043.     $value = $hashref->{$key};
  1044.     return($hashref) unless(ref($value) eq 'HASH');
  1045.  
  1046.     if(ref($self->{opt}->{keyattr}) eq 'HASH') {
  1047.       return($hashref) unless(defined($self->{opt}->{keyattr}->{$parent}));
  1048.       push(@$arrayref, { $self->{opt}->{keyattr}->{$parent}->[0] => $key,
  1049.                          %$value });
  1050.     }
  1051.     else {
  1052.       push(@$arrayref, { $self->{opt}->{keyattr}->[0] => $key, %$value });
  1053.     }
  1054.   }
  1055.  
  1056.   return($arrayref);
  1057. }
  1058.  
  1059. 1;
  1060.  
  1061. __END__
  1062.  
  1063. =head1 QUICK START
  1064.  
  1065. Say you have a script called B<foo> and a file of configuration options
  1066. called B<foo.xml> containing this:
  1067.  
  1068.   <config logdir="/var/log/foo/" debugfile="/tmp/foo.debug">
  1069.     <server name="sahara" osname="solaris" osversion="2.6">
  1070.       <address>10.0.0.101</address>
  1071.       <address>10.0.1.101</address>
  1072.     </server>
  1073.     <server name="gobi" osname="irix" osversion="6.5">
  1074.       <address>10.0.0.102</address>
  1075.     </server>
  1076.     <server name="kalahari" osname="linux" osversion="2.0.34">
  1077.       <address>10.0.0.103</address>
  1078.       <address>10.0.1.103</address>
  1079.     </server>
  1080.   </config>
  1081.  
  1082. The following lines of code in B<foo>:
  1083.  
  1084.   use XML::Simple;
  1085.  
  1086.   my $config = XMLin();
  1087.  
  1088. will 'slurp' the configuration options into the hashref $config (because no
  1089. arguments are passed to C<XMLin()> the name and location of the XML file will
  1090. be inferred from name and location of the script).  You can dump out the
  1091. contents of the hashref using Data::Dumper:
  1092.  
  1093.   use Data::Dumper;
  1094.  
  1095.   print Dumper($config);
  1096.  
  1097. which will produce something like this (formatting has been adjusted for
  1098. brevity):
  1099.  
  1100.   {
  1101.       'logdir'        => '/var/log/foo/',
  1102.       'debugfile'     => '/tmp/foo.debug',
  1103.       'server'        => {
  1104.       'sahara'        => {
  1105.           'osversion'     => '2.6',
  1106.           'osname'        => 'solaris',
  1107.           'address'       => [ '10.0.0.101', '10.0.1.101' ]
  1108.       },
  1109.       'gobi'          => {
  1110.           'osversion'     => '6.5',
  1111.           'osname'        => 'irix',
  1112.           'address'       => '10.0.0.102'
  1113.       },
  1114.       'kalahari'      => {
  1115.           'osversion'     => '2.0.34',
  1116.           'osname'        => 'linux',
  1117.           'address'       => [ '10.0.0.103', '10.0.1.103' ]
  1118.       }
  1119.       }
  1120.   }
  1121.  
  1122. Your script could then access the name of the log directory like this:
  1123.  
  1124.   print $config->{logdir};
  1125.  
  1126. similarly, the second address on the server 'kalahari' could be referenced as:
  1127.  
  1128.   print $config->{server}->{kalahari}->{address}->[1];
  1129.  
  1130. What could be simpler?  (Rhetorical).
  1131.  
  1132. For simple requirements, that's really all there is to it.  If you want to
  1133. store your XML in a different directory or file, or pass it in as a string or
  1134. even pass it in via some derivative of an IO::Handle, you'll need to check out
  1135. L<"OPTIONS">.  If you want to turn off or tweak the array folding feature (that
  1136. neat little transformation that produced $config->{server}) you'll find options
  1137. for that as well.
  1138.  
  1139. If you want to generate XML (for example to write a modified version of
  1140. $config back out as XML), check out C<XMLout()>.
  1141.  
  1142. If your needs are not so simple, this may not be the module for you.  In that
  1143. case, you might want to read L<"WHERE TO FROM HERE?">.
  1144.  
  1145. =head1 DESCRIPTION
  1146.  
  1147. The XML::Simple module provides a simple API layer on top of the XML::Parser
  1148. module.  Two functions are exported: C<XMLin()> and C<XMLout()>.
  1149.  
  1150. The most common approach is to simply call these two functions directly, but an
  1151. optional object oriented interface (see L<"OPTIONAL OO INTERFACE"> below)
  1152. allows them to be called as methods of an B<XML::Simple> object.
  1153.  
  1154. =head2 XMLin()
  1155.  
  1156. Parses XML formatted data and returns a reference to a data structure which
  1157. contains the same information in a more readily accessible form.  (Skip
  1158. down to L<"EXAMPLES"> below, for more sample code).
  1159.  
  1160. C<XMLin()> accepts an optional XML specifier followed by zero or more 'name =>
  1161. value' option pairs.  The XML specifier can be one of the following:
  1162.  
  1163. =over 4
  1164.  
  1165. =item A filename
  1166.  
  1167. If the filename contains no directory components C<XMLin()> will look for the
  1168. file in each directory in the searchpath (see L<"OPTIONS"> below).  eg:
  1169.  
  1170.   $ref = XMLin('/etc/params.xml');
  1171.  
  1172. Note, the filename '-' can be used to parse from STDIN.
  1173.  
  1174. =item undef
  1175.  
  1176. If there is no XML specifier, C<XMLin()> will check the script directory and
  1177. each of the searchpath directories for a file with the same name as the script
  1178. but with the extension '.xml'.  Note: if you wish to specify options, you
  1179. must specify the value 'undef'.  eg:
  1180.  
  1181.   $ref = XMLin(undef, forcearray => 1);
  1182.  
  1183. =item A string of XML
  1184.  
  1185. A string containing XML (recognised by the presence of '<' and '>' characters)
  1186. will be parsed directly.  eg:
  1187.  
  1188.   $ref = XMLin('<opt username="bob" password="flurp" />');
  1189.  
  1190. =item An IO::Handle object
  1191.  
  1192. An IO::Handle object will be read to EOF and its contents parsed. eg:
  1193.  
  1194.   $fh = new IO::File('/etc/params.xml');
  1195.   $ref = XMLin($fh);
  1196.  
  1197. =back
  1198.  
  1199. =head2 XMLout()
  1200.  
  1201. Takes a data structure (generally a hashref) and returns an XML encoding of
  1202. that structure.  If the resulting XML is parsed using C<XMLin()>, it will
  1203. return a data structure equivalent to the original. 
  1204.  
  1205. When translating hashes to XML, hash keys which have a leading '-' will be
  1206. silently skipped.  This is the approved method for marking elements of a
  1207. data structure which should be ignored by C<XMLout>.  (Note: If these items
  1208. were not skipped the key names would be emitted as element or attribute names
  1209. with a leading '-' which would not be valid XML).
  1210.  
  1211. =head2 Caveats
  1212.  
  1213. Some care is required in creating data structures which will be passed to
  1214. C<XMLout()>.  Hash keys from the data structure will be encoded as either XML
  1215. element names or attribute names.  Therefore, you should use hash key names 
  1216. which conform to the relatively strict XML naming rules:
  1217.  
  1218. Names in XML must begin with a letter.  The remaining characters may be
  1219. letters, digits, hyphens (-), underscores (_) or full stops (.).  It is also
  1220. allowable to include one colon (:) in an element name but this should only be
  1221. used when working with namespaces - a facility well beyond the scope of
  1222. B<XML::Simple>.
  1223.  
  1224. You can use other punctuation characters in hash values (just not in hash
  1225. keys) however B<XML::Simple> does not support dumping binary data.
  1226.  
  1227. If you break these rules, the current implementation of C<XMLout()> will 
  1228. simply emit non-compliant XML which will be rejected if you try to read it
  1229. back in.  (A later version of B<XML::Simple> might take a more proactive
  1230. approach).
  1231.  
  1232. Note also that although you can nest hashes and arrays to arbitrary levels,
  1233. recursive data structures are not supported and will cause C<XMLout()> to die.
  1234.  
  1235. Refer to L<"WHERE TO FROM HERE?"> if C<XMLout()> is too simple for your needs.
  1236.  
  1237.  
  1238. =head1 OPTIONS
  1239.  
  1240. B<XML::Simple> supports a number of options (in fact as each release of
  1241. B<XML::Simple> adds more options, the module's claim to the name 'Simple'
  1242. becomes more tenuous).  If you find yourself repeatedly having to specify
  1243. the same options, you might like to investigate L<"OPTIONAL OO INTERFACE">
  1244. below.
  1245.  
  1246. Because there are so many options, it's hard for new users to know which ones
  1247. are important, so here are the two you really need to know about:
  1248.  
  1249. =over 4
  1250.  
  1251. =item *
  1252.  
  1253. check out 'forcearray' because you'll almost certainly want to turn it on
  1254.  
  1255. =item *
  1256.  
  1257. make sure you know what the 'keyattr' option does and what its default value
  1258. is because it may surprise you otherwise
  1259.  
  1260. =back
  1261.  
  1262. Both C<XMLin()> and C<XMLout()> expect a single argument followed by a list of
  1263. options.  An option takes the form of a 'name => value' pair.  The options
  1264. listed below are marked with 'B<in>' if they are recognised by C<XMLin()> and
  1265. 'B<out>' if they are recognised by C<XMLout()>.
  1266.  
  1267. =over 4
  1268.  
  1269. =item keyattr => [ list ] (B<in+out>)
  1270.  
  1271. This option controls the 'array folding' feature which translates nested
  1272. elements from an array to a hash.  For example, this XML:
  1273.  
  1274.     <opt>
  1275.       <user login="grep" fullname="Gary R Epstein" />
  1276.       <user login="stty" fullname="Simon T Tyson" />
  1277.     </opt>
  1278.  
  1279. would, by default, parse to this:
  1280.  
  1281.     {
  1282.       'user' => [
  1283.           {
  1284.             'login' => 'grep',
  1285.             'fullname' => 'Gary R Epstein'
  1286.           },
  1287.           {
  1288.             'login' => 'stty',
  1289.             'fullname' => 'Simon T Tyson'
  1290.           }
  1291.         ]
  1292.     }
  1293.  
  1294. If the option 'keyattr => "login"' were used to specify that the 'login'
  1295. attribute is a key, the same XML would parse to:
  1296.  
  1297.     {
  1298.       'user' => {
  1299.           'stty' => {
  1300.                   'fullname' => 'Simon T Tyson'
  1301.                 },
  1302.           'grep' => {
  1303.                   'fullname' => 'Gary R Epstein'
  1304.                 }
  1305.         }
  1306.     }
  1307.  
  1308. The key attribute names should be supplied in an arrayref if there is more
  1309. than one.  C<XMLin()> will attempt to match attribute names in the order
  1310. supplied.  C<XMLout()> will use the first attribute name supplied when
  1311. 'unfolding' a hash into an array.
  1312.  
  1313. Note: the keyattr option controls the folding of arrays.  By default a single
  1314. nested element will be rolled up into a scalar rather than an array and
  1315. therefore will not be folded.  Use the 'forcearray' option (below) to force
  1316. nested elements to be parsed into arrays and therefore candidates for folding
  1317. into hashes.
  1318.  
  1319. The default value for 'keyattr' is ['name', 'key', 'id'].  Setting this option
  1320. to an empty list will disable the array folding feature.
  1321.  
  1322. =item keyattr => { list } (B<in+out>)
  1323.  
  1324. This alternative method of specifiying the key attributes allows more fine
  1325. grained control over which elements are folded and on which attributes.  For
  1326. example the option 'keyattr => { package => 'id' } will cause any package
  1327. elements to be folded on the 'id' attribute.  No other elements which have an
  1328. 'id' attribute will be folded at all. 
  1329.  
  1330. Note: C<XMLin()> will generate a warning if this syntax is used and an element
  1331. which does not have the specified key attribute is encountered (eg: a 'package'
  1332. element without an 'id' attribute, to use the example above).  Warnings will
  1333. only be generated if B<-w> is in force.
  1334.  
  1335. Two further variations are made possible by prefixing a '+' or a '-' character
  1336. to the attribute name:
  1337.  
  1338. The option 'keyattr => { user => "+login" }' will cause this XML:
  1339.  
  1340.     <opt>
  1341.       <user login="grep" fullname="Gary R Epstein" />
  1342.       <user login="stty" fullname="Simon T Tyson" />
  1343.     </opt>
  1344.  
  1345. to parse to this data structure:
  1346.  
  1347.     {
  1348.       'user' => {
  1349.           'stty' => {
  1350.                   'fullname' => 'Simon T Tyson',
  1351.                   'login'    => 'stty'
  1352.                 },
  1353.           'grep' => {
  1354.                   'fullname' => 'Gary R Epstein',
  1355.                   'login'    => 'grep'
  1356.                 }
  1357.         }
  1358.     }
  1359.  
  1360. The '+' indicates that the value of the key attribute should be copied rather than
  1361. moved to the folded hash key.
  1362.  
  1363. A '-' prefix would produce this result:
  1364.  
  1365.     {
  1366.       'user' => {
  1367.           'stty' => {
  1368.                   'fullname' => 'Simon T Tyson',
  1369.                   '-login'    => 'stty'
  1370.                 },
  1371.           'grep' => {
  1372.                   'fullname' => 'Gary R Epstein',
  1373.                   '-login'    => 'grep'
  1374.                 }
  1375.         }
  1376.     }
  1377.  
  1378. As described earlier, C<XMLout> will ignore hash keys starting with a '-'.
  1379.  
  1380. =item searchpath => [ list ] (B<in>)
  1381.  
  1382. Where the XML is being read from a file, and no path to the file is specified,
  1383. this attribute allows you to specify which directories should be searched.
  1384.  
  1385. If the first parameter to C<XMLin()> is undefined, the default searchpath
  1386. will contain only the directory in which the script itself is located.
  1387. Otherwise the default searchpath will be empty.  
  1388.  
  1389. Note: the current directory ('.') is B<not> searched unless it is the directory
  1390. containing the script.
  1391.  
  1392. =item forcearray => 1 (B<in>)
  1393.  
  1394. This option should be set to '1' to force nested elements to be represented
  1395. as arrays even when there is only one.  Eg, with forcearray enabled, this
  1396. XML:
  1397.  
  1398.     <opt>
  1399.       <name>value</name>
  1400.     </opt>
  1401.  
  1402. would parse to this:
  1403.  
  1404.     {
  1405.       'name' => [
  1406.           'value'
  1407.         ]
  1408.     }
  1409.  
  1410. instead of this (the default):
  1411.  
  1412.     {
  1413.       'name' => 'value'
  1414.     }
  1415.  
  1416. This option is especially useful if the data structure is likely to be written
  1417. back out as XML and the default behaviour of rolling single nested elements up
  1418. into attributes is not desirable. 
  1419.  
  1420. If you are using the array folding feature, you should almost certainly enable
  1421. this option.  If you do not, single nested elements will not be parsed to
  1422. arrays and therefore will not be candidates for folding to a hash.  (Given that
  1423. the default value of 'keyattr' enables array folding, the default value of this
  1424. option should probably also have been enabled too - sorry).
  1425.  
  1426. =item forcearray => [ name(s) ] (B<in>)
  1427.  
  1428. This alternative form of the 'forcearray' option allows you to specify a list
  1429. of element names which should always be forced into an array representation,
  1430. rather than the 'all or nothing' approach above.
  1431.  
  1432. =item noattr => 1 (B<in+out>)
  1433.  
  1434. When used with C<XMLout()>, the generated XML will contain no attributes.
  1435. All hash key/values will be represented as nested elements instead.
  1436.  
  1437. When used with C<XMLin()>, any attributes in the XML will be ignored.
  1438.  
  1439. =item suppressempty => 1 | '' | undef (B<in>)
  1440.  
  1441. This option controls what C<XMLin()> should do with empty elements (no
  1442. attributes and no content).  The default behaviour is to represent them as
  1443. empty hashes.  Setting this option to a true value (eg: 1) will cause empty
  1444. elements to be skipped altogether.  Setting the option to 'undef' or the empty
  1445. string will cause empty elements to be represented as the undefined value or
  1446. the empty string respectively.  The latter two alternatives are a little
  1447. easier to test for in your code than a hash with no keys.
  1448.  
  1449. =item cache => [ cache scheme(s) ] (B<in>)
  1450.  
  1451. Because loading the B<XML::Parser> module and parsing an XML file can consume a
  1452. significant number of CPU cycles, it is often desirable to cache the output of
  1453. C<XMLin()> for later reuse.
  1454.  
  1455. When parsing from a named file, B<XML::Simple> supports a number of caching
  1456. schemes.  The 'cache' option may be used to specify one or more schemes (using
  1457. an anonymous array).  Each scheme will be tried in turn in the hope of finding
  1458. a cached pre-parsed representation of the XML file.  If no cached copy is
  1459. found, the file will be parsed and the first cache scheme in the list will be
  1460. used to save a copy of the results.  The following cache schemes have been
  1461. implemented:
  1462.  
  1463. =over 4
  1464.  
  1465. =item storable
  1466.  
  1467. Utilises B<Storable.pm> to read/write a cache file with the same name as the
  1468. XML file but with the extension .stor
  1469.  
  1470. =item memshare
  1471.  
  1472. When a file is first parsed, a copy of the resulting data structure is retained
  1473. in memory in the B<XML::Simple> module's namespace.  Subsequent calls to parse
  1474. the same file will return a reference to this structure.  This cached version
  1475. will persist only for the life of the Perl interpreter (which in the case of
  1476. mod_perl for example, may be some significant time).
  1477.  
  1478. Because each caller receives a reference to the same data structure, a change
  1479. made by one caller will be visible to all.  For this reason, the reference
  1480. returned should be treated as read-only.
  1481.  
  1482. =item memcopy
  1483.  
  1484. This scheme works identically to 'memshare' (above) except that each caller
  1485. receives a reference to a new data structure which is a copy of the cached
  1486. version.  Copying the data structure will add a little processing overhead,
  1487. therefore this scheme should only be used where the caller intends to modify
  1488. the data structure (or wishes to protect itself from others who might).  This
  1489. scheme uses B<Storable.pm> to perform the copy.
  1490.  
  1491. =back
  1492.  
  1493. =item keeproot => 1 (B<in+out>)
  1494.  
  1495. In its attempt to return a data structure free of superfluous detail and
  1496. unnecessary levels of indirection, C<XMLin()> normally discards the root
  1497. element name.  Setting the 'keeproot' option to '1' will cause the root element
  1498. name to be retained.  So after executing this code:
  1499.  
  1500.   $config = XMLin('<config tempdir="/tmp" />', keeproot => 1)
  1501.  
  1502. You'll be able to reference the tempdir as
  1503. C<$config-E<gt>{config}-E<gt>{tempdir}> instead of the default
  1504. C<$config-E<gt>{tempdir}>.
  1505.  
  1506. Similarly, setting the 'keeproot' option to '1' will tell C<XMLout()> that the
  1507. data structure already contains a root element name and it is not necessary to
  1508. add another.
  1509.  
  1510. =item rootname => 'string' (B<out>)
  1511.  
  1512. By default, when C<XMLout()> generates XML, the root element will be named
  1513. 'opt'.  This option allows you to specify an alternative name.
  1514.  
  1515. Specifying either undef or the empty string for the rootname option will
  1516. produce XML with no root elements.  In most cases the resulting XML fragment
  1517. will not be 'well formed' and therefore could not be read back in by C<XMLin()>.
  1518. Nevertheless, the option has been found to be useful in certain circumstances.
  1519.  
  1520. =item forcecontent (B<in>)
  1521.  
  1522. When C<XMLin()> parses elements which have text content as well as attributes,
  1523. the text content must be represented as a hash value rather than a simple
  1524. scalar.  This option allows you to force text content to always parse to
  1525. a hash value even when there are no attributes.  So for example:
  1526.  
  1527.   XMLin('<opt><x>text1</x><y a="2">text2</y></opt>', forcecontent => 1)
  1528.  
  1529. will parse to:
  1530.  
  1531.   {
  1532.     'x' => {           'content' => 'text1' },
  1533.     'y' => { 'a' => 2, 'content' => 'text2' }
  1534.   }
  1535.  
  1536. instead of:
  1537.  
  1538.   {
  1539.     'x' => 'text1',
  1540.     'y' => { 'a' => 2, 'content' => 'text2' }
  1541.   }
  1542.  
  1543. =item contentkey => 'keyname' (B<in+out>)
  1544.  
  1545. When text content is parsed to a hash value, this option let's you specify a
  1546. name for the hash key to override the default 'content'.  So for example:
  1547.  
  1548.   XMLin('<opt one="1">Text</opt>', contentkey => 'text')
  1549.  
  1550. will parse to:
  1551.  
  1552.   { 'one' => 1, 'text' => 'Text' }
  1553.  
  1554. instead of:
  1555.  
  1556.   { 'one' => 1, 'content' => 'Text' }
  1557.  
  1558. C<XMLout()> will also honour the value of this option when converting a hashref
  1559. to XML.
  1560.  
  1561. =item xmldecl => 1  or  xmldecl => 'string'  (B<out>)
  1562.  
  1563. If you want the output from C<XMLout()> to start with the optional XML
  1564. declaration, simply set the option to '1'.  The default XML declaration is:
  1565.  
  1566.         <?xml version='1.0' standalone='yes'?>
  1567.  
  1568. If you want some other string (for example to declare an encoding value), set
  1569. the value of this option to the complete string you require.
  1570.  
  1571. =item outputfile => <file specifier> (B<out>)
  1572.  
  1573. The default behaviour of C<XMLout()> is to return the XML as a string.  If you
  1574. wish to write the XML to a file, simply supply the filename using the
  1575. 'outputfile' option.  Alternatively, you can supply an IO handle object instead
  1576. of a filename.
  1577.  
  1578. =item noescape => 1 (B<out>)
  1579.  
  1580. By default, C<XMLout()> will translate the characters 'E<lt>', 'E<gt>', '&' and
  1581. '"' to '<', '>', '&' and '"' respectively.  Use this option to
  1582. suppress escaping (presumably because you've already escaped the data in some
  1583. more sophisticated manner).
  1584.  
  1585. =item parseropts => [ XML::Parser Options ] (B<in>)
  1586.  
  1587. Use this option to specify parameters that should be passed to the constructor
  1588. of the underlying XML::Parser object.  For example to turn on the namespace processing mode, you could say:
  1589.  
  1590.   XMLin($xml, parseropts => [ Namespaces => 1 ])
  1591.  
  1592. =back
  1593.  
  1594. =head1 OPTIONAL OO INTERFACE
  1595.  
  1596. The procedural interface is both simple and convenient however there are a
  1597. couple of reasons why you might prefer to use the object oriented (OO)
  1598. interface:
  1599.  
  1600. =over 4
  1601.  
  1602. =item *
  1603.  
  1604. to define a set of default values which should be used on all subsequent calls
  1605. to C<XMLin()> or C<XMLout()>
  1606.  
  1607. =item *
  1608.  
  1609. to override methods in B<XML::Simple> to provide customised behaviour
  1610.  
  1611. =back
  1612.  
  1613. The default values for the options described above are unlikely to suit
  1614. everyone.  The OO interface allows you to effectively override B<XML::Simple>'s
  1615. defaults with your preferred values.  It works like this:
  1616.  
  1617. First create an XML::Simple parser object with your preferred defaults:
  1618.  
  1619.   my $xs = new XML::Simple(forcearray => 1, keeproot => 1);
  1620.  
  1621. then call C<XMLin()> or C<XMLout()> as a method of that object:
  1622.  
  1623.   my $ref = $xs->XMLin($xml);
  1624.   my $xml = $xs->XMLout($ref);
  1625.  
  1626. You can also specify options when you make the method calls and these values
  1627. will be merged with the values specified when the object was created.  Values
  1628. specified in a method call take precedence.
  1629.  
  1630. Overriding methods is a more advanced topic but might be useful if for example
  1631. you wished to provide an alternative routine for escaping character data (the
  1632. escape_value method) or for building the initial parse tree (the build_tree
  1633. method).
  1634.  
  1635. =head1 ERROR HANDLING
  1636.  
  1637. The XML standard is very clear on the issue of non-compliant documents.  An
  1638. error in parsing any single element (for example a missing end tag) must cause
  1639. the whole document to be rejected.  B<XML::Simple> will die with an
  1640. appropriate message if it encounters a parsing error.
  1641.  
  1642. If dying is not appropriate for your application, you should arrange to call
  1643. C<XMLin()> in an eval block and look for errors in $@.  eg:
  1644.  
  1645.     my $config = eval { XMLin() };
  1646.     PopUpMessage($@) if($@);
  1647.  
  1648. Note, there is a common misconception that use of B<eval> will significantly
  1649. slow down a script.  While that may be true when the code being eval'd is in a
  1650. string, it is not true of code like the sample above.
  1651.  
  1652. =head1 EXAMPLES
  1653.  
  1654. When C<XMLin()> reads the following very simple piece of XML:
  1655.  
  1656.     <opt username="testuser" password="frodo"></opt>
  1657.  
  1658. it returns the following data structure:
  1659.  
  1660.     {
  1661.       'username' => 'testuser',
  1662.       'password' => 'frodo'
  1663.     }
  1664.  
  1665. The identical result could have been produced with this alternative XML:
  1666.  
  1667.     <opt username="testuser" password="frodo" />
  1668.  
  1669. Or this (although see 'forcearray' option for variations):
  1670.  
  1671.     <opt>
  1672.       <username>testuser</username>
  1673.       <password>frodo</password>
  1674.     </opt>
  1675.  
  1676. Repeated nested elements are represented as anonymous arrays:
  1677.  
  1678.     <opt>
  1679.       <person firstname="Joe" lastname="Smith">
  1680.         <email>joe@smith.com</email>
  1681.         <email>jsmith@yahoo.com</email>
  1682.       </person>
  1683.       <person firstname="Bob" lastname="Smith">
  1684.         <email>bob@smith.com</email>
  1685.       </person>
  1686.     </opt>
  1687.  
  1688.     {
  1689.       'person' => [
  1690.                     {
  1691.                       'email' => [
  1692.                                    'joe@smith.com',
  1693.                                    'jsmith@yahoo.com'
  1694.                                  ],
  1695.                       'firstname' => 'Joe',
  1696.                       'lastname' => 'Smith'
  1697.                     },
  1698.                     {
  1699.                       'email' => 'bob@smith.com',
  1700.                       'firstname' => 'Bob',
  1701.                       'lastname' => 'Smith'
  1702.                     }
  1703.                   ]
  1704.     }
  1705.  
  1706. Nested elements with a recognised key attribute are transformed (folded) from
  1707. an array into a hash keyed on the value of that attribute:
  1708.  
  1709.     <opt>
  1710.       <person key="jsmith" firstname="Joe" lastname="Smith" />
  1711.       <person key="tsmith" firstname="Tom" lastname="Smith" />
  1712.       <person key="jbloggs" firstname="Joe" lastname="Bloggs" />
  1713.     </opt>
  1714.  
  1715.     {
  1716.       'person' => {
  1717.                     'jbloggs' => {
  1718.                                    'firstname' => 'Joe',
  1719.                                    'lastname' => 'Bloggs'
  1720.                                  },
  1721.                     'tsmith' => {
  1722.                                   'firstname' => 'Tom',
  1723.                                   'lastname' => 'Smith'
  1724.                                 },
  1725.                     'jsmith' => {
  1726.                                   'firstname' => 'Joe',
  1727.                                   'lastname' => 'Smith'
  1728.                                 }
  1729.                   }
  1730.     }
  1731.  
  1732.  
  1733. The <anon> tag can be used to form anonymous arrays:
  1734.  
  1735.     <opt>
  1736.       <head><anon>Col 1</anon><anon>Col 2</anon><anon>Col 3</anon></head>
  1737.       <data><anon>R1C1</anon><anon>R1C2</anon><anon>R1C3</anon></data>
  1738.       <data><anon>R2C1</anon><anon>R2C2</anon><anon>R2C3</anon></data>
  1739.       <data><anon>R3C1</anon><anon>R3C2</anon><anon>R3C3</anon></data>
  1740.     </opt>
  1741.  
  1742.     {
  1743.       'head' => [
  1744.           [ 'Col 1', 'Col 2', 'Col 3' ]
  1745.         ],
  1746.       'data' => [
  1747.           [ 'R1C1', 'R1C2', 'R1C3' ],
  1748.           [ 'R2C1', 'R2C2', 'R2C3' ],
  1749.           [ 'R3C1', 'R3C2', 'R3C3' ]
  1750.         ]
  1751.     }
  1752.  
  1753. Anonymous arrays can be nested to arbirtrary levels and as a special case, if
  1754. the surrounding tags for an XML document contain only an anonymous array the
  1755. arrayref will be returned directly rather than the usual hashref:
  1756.  
  1757.     <opt>
  1758.       <anon><anon>Col 1</anon><anon>Col 2</anon></anon>
  1759.       <anon><anon>R1C1</anon><anon>R1C2</anon></anon>
  1760.       <anon><anon>R2C1</anon><anon>R2C2</anon></anon>
  1761.     </opt>
  1762.  
  1763.     [
  1764.       [ 'Col 1', 'Col 2' ],
  1765.       [ 'R1C1', 'R1C2' ],
  1766.       [ 'R2C1', 'R2C2' ]
  1767.     ]
  1768.  
  1769. Elements which only contain text content will simply be represented as a
  1770. scalar.  Where an element has both attributes and text content, the element
  1771. will be represented as a hashref with the text content in the 'content' key:
  1772.  
  1773.   <opt>
  1774.     <one>first</one>
  1775.     <two attr="value">second</two>
  1776.   </opt>
  1777.  
  1778.   {
  1779.     'one' => 'first',
  1780.     'two' => { 'attr' => 'value', 'content' => 'second' }
  1781.   }
  1782.  
  1783. Mixed content (elements which contain both text content and nested elements)
  1784. will be not be represented in a useful way - element order and significant
  1785. whitespace will be lost.  If you need to work with mixed content, then
  1786. XML::Simple is not the right tool for your job - check out the next section.
  1787.  
  1788. =head1 WHERE TO FROM HERE?
  1789.  
  1790. B<XML::Simple> is by nature very simple.  
  1791.  
  1792. =over 4
  1793.  
  1794. =item *
  1795.  
  1796. The parsing process liberally disposes of 'surplus' whitespace - some 
  1797. applications will be sensitive to this.
  1798.  
  1799. =item *
  1800.  
  1801. Slurping data into a hash will implicitly discard information about attribute
  1802. order.  Normally this would not be a problem because any items for which order
  1803. is important would typically be encoded as elements rather than attributes.
  1804. However B<XML::Simple>'s aggressive slurping and folding algorithms can
  1805. defeat even these techniques.
  1806.  
  1807. =item *
  1808.  
  1809. The API offers little control over the output of C<XMLout()>.  In particular,
  1810. it is not especially likely that feeding the output from C<XMLin()> into
  1811. C<XMLout()> will reproduce the original XML (although passing the output from
  1812. C<XMLout()> into C<XMLin()> should reproduce the original data structure).
  1813.  
  1814. =item *
  1815.  
  1816. C<XMLout()> cannot produce well formed HTML unless you feed it with care - hash
  1817. keys must conform to XML element naming rules and undefined values should be
  1818. avoided.
  1819.  
  1820. =item *
  1821.  
  1822. C<XMLout()> does not currently support encodings (although it shouldn't stand
  1823. in your way if you feed it encoded data).
  1824.  
  1825. =item *
  1826.  
  1827. If you're attempting to get the output from C<XMLout()> to conform to a
  1828. specific DTD, you're almost certainly using the wrong tool for the job.
  1829.  
  1830. =back
  1831.  
  1832. If any of these points are a problem for you, then B<XML::Simple> is probably
  1833. not the right module for your application.  The following section is intended
  1834. to give pointers which might help you select a more powerful tool - it's a bit
  1835. sketchy right now but submissions are welcome.
  1836.  
  1837. =over 4
  1838.  
  1839. =item XML::Parser
  1840.  
  1841. B<XML::Simple> is built on top of B<XML::Parser>, so if you have B<XML::Simple>
  1842. working you already have B<XML::Parser> installed.  This is a comprehensive,
  1843. fast, industrial strength (non-validating) parsing tool built on top of James
  1844. Clark's 'expat' library.  It does support converting XML into a Perl tree
  1845. structure (with full support for mixed content) but for arbritrarily large
  1846. documents you're probably better off defining handler routines for
  1847. B<XML::Parser> to call as each element is parsed.  The distribution includes a
  1848. number of sample applications.
  1849.  
  1850. =item XML::DOM
  1851.  
  1852. The data structure returned by B<XML::Simple> was designed for convenience
  1853. rather than standards compliance.  B<XML::DOM> is a parser built on top of
  1854. B<XML::Parser>, which returns a 'Document' object conforming to the API of the
  1855. Document Object Model as described at http://www.w3.org/TR/REC-DOM-Level-1 .
  1856. This Document object can then be examined, modified and written back out to a
  1857. file or converted to a string. 
  1858.  
  1859. =item XML::Grove
  1860.  
  1861. Compliance with the Document Object Model might be particularly useful when
  1862. porting code to or from another language.  However, if you're looking for a
  1863. simpler, 'perlish' object interface, take a look at B<XML::Grove>.
  1864.  
  1865. =item XML::Twig
  1866.  
  1867. XML::Twig offers a tree-oriented interface to a document while still allowing
  1868. the processing of documents of any size. It allows processing chunks of
  1869. documents in tree-mode which can then be flushed or purged from the memory.
  1870. The XML::Twig page is at http://standards.ieee.org/resources/spasystem/twig/
  1871.  
  1872. =item libxml-perl
  1873.  
  1874. B<libxml-perl> is a collection of Perl modules, scripts, and documents for
  1875. working with XML in Perl. The distribution includes PerlSAX - a Perl
  1876. implementation of the SAX API.  It also include B<XML::PatAct> modules for
  1877. processing XML by defining patterns and associating them with actions.  For more
  1878. details see http://bitsko.slc.ut.us/libxml-perl/ .
  1879.  
  1880. =item XML::PYX
  1881.  
  1882. B<XML::PYX> allows you to apply Unix command pipelines (using grep, sed etc) to
  1883. filter or transform XML files.  Ideally suited for tasks such as extracting all
  1884. text content or stripping out all occurrences of a particular tag without
  1885. having to write a Perl script at all.  It can also be used for transforming
  1886. HTML to XHTML.
  1887.  
  1888. =item XML::RAX
  1889.  
  1890. If you wish to process XML files containing a series of 'records', B<XML::RAX>
  1891. provides a simple purpose-designed interface.  If it still hasn't made it to
  1892. CPAN, try: http://www.dancentury.com/robh/
  1893.  
  1894. =item XML::Writer
  1895.  
  1896. B<XML::Writer> is a helper module for Perl programs that write XML documents.
  1897.  
  1898. =item XML::Dumper
  1899.  
  1900. B<XML::Dumper> dumps Perl data to a structured XML format. B<XML::Dumper> can
  1901. also read XML data that was previously dumped by the module and convert it back
  1902. to Perl. 
  1903.  
  1904. =back
  1905.  
  1906. Don't forget to check out the Perl XML FAQ at:
  1907. http://www.perlxml.com/faq/perl-xml-faq.html
  1908.  
  1909.  
  1910. =head1 STATUS
  1911.  
  1912. This version (1.08) is the current stable version.
  1913.  
  1914. =head1 SEE ALSO
  1915.  
  1916. B<XML::Simple> requires B<XML::Parser> and B<File::Spec>.  The optional caching
  1917. functions require B<Storable>.
  1918.  
  1919. =head1 COPYRIGHT 
  1920.  
  1921. Copyright 1999-2001 Grant McLean E<lt>grantm@cpan.orgE<gt>
  1922.  
  1923. This library is free software; you can redistribute it and/or modify it
  1924. under the same terms as Perl itself. 
  1925.  
  1926. =cut
  1927.  
  1928.  
  1929.